import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import '../../resources/kq_theme_colors.dart';
import 'base/kq_chart_model.dart';
import 'kq_chart_line_model.dart';

class KqChartBarModel extends GetxController {
  KqChartModel chartModel;

  ///折线数据集合
  List<List<ChartBarValue>> chartBarArray;

  ///柱状图颜色数组与chartBarArray一一对应，在ChartBarValue中barColor为null时使用
  List<Color>? barColors;

  ///柱状图宽度数组与chartBarArray一一对应，在ChartBarValue中barWidth为null时使用。默认5
  List<double>? barWidths;

  ///柱状图之间的间距默认4，chartBarArray大于2时才会被使用
  double? interval;

  ///折线数据集合,不存在遮罩层
  List<List<ChartLineValue>>? chartLineArray;

  ///线颜色数组与chartLineArray一一对应，在ChartBarValue中barColor为null时使用
  List<Color>? lineColors;

  KqChartBarModel({
    required this.chartBarArray,
    required this.chartModel,
    this.chartLineArray,
    this.barColors,
    this.barWidths,
    this.interval,
  });

  /**以下均为内部计算无需传入 */
  ///实际高度
  double yHeight = 0;

  ///实际宽度
  double xWidth = 0;

  ///横坐标间距
  double crossSpacing = 0;

  int maxCross = 0;

  double maxHeight = 0;

  ///横坐标数组
  List xList = [];

  ///横坐标内容
  List xValue = [];

  ///纵坐标数组
  List yList = [];

  ///纵坐标内容
  List yValue = [];

  ///平均线坐标数组
  List<double> avgYPointList = [];

  //初始化内容
  void _initData() {
    chartModel.initData();
    chartModel.xColor = chartModel.xColor ?? KqThemeColors.text59;
    chartModel.yColor = chartModel.yColor ?? KqThemeColors.text59;
    chartModel.axisColor = chartModel.axisColor ?? KqThemeColors.bgD8;
    chartModel.dividerColor = chartModel.dividerColor ?? KqThemeColors.bgF5;
    maxCross = 0;
    maxHeight = 0;
    interval = interval ?? 4.sp;
    yHeight = chartModel.sizeHeight -
        chartModel.yTop! -
        chartModel.yBottom! -
        chartModel.yAxisTop!;
    xWidth = chartModel.sizeWidth - chartModel.xLeft! - chartModel.xRight!;
  }

  ///设置内容
  void setValueList(List<List<ChartBarValue>> barList,
      {List<List<ChartLineValue>>? lineList}) {
    _initData();
    for (var i = 0; i < barList.length; i++) {
      List<ChartBarValue> e = barList[i];
      maxCross = maxCross > e.length ? maxCross : e.length;
      e.map((ChartBarValue value) {
        value.barWidth =
            value.barWidth ?? (barWidths == null ? 16.r : barWidths![i]);
      }).toList();
    }
    if (lineList != null && lineList.isNotEmpty) {
      lineList.map((List<ChartLineValue> e) {
        maxCross = maxCross > e.length ? maxCross : e.length;
      }).toList();
    }
    chartBarArray = barList;
    chartLineArray = lineList;
    if (!chartModel.isFixMaxY) {
      for (var i = 0; i < chartBarArray.length; i++) {
        List<ChartBarValue> e = chartBarArray[i];
        e.map((ChartBarValue value) {
          double y = double.parse(value.yValue);
          if (chartModel.maxY > y) {
            maxHeight =
                maxHeight > chartModel.maxY ? maxHeight : chartModel.maxY;
          } else {
            maxHeight = maxHeight > y ? maxHeight : y;
          }
        }).toList();
      }
      if (chartLineArray != null && chartLineArray!.isNotEmpty) {
        chartLineArray!.map((List<ChartLineValue> e) {
          e.map((ChartLineValue value) {
            double y = double.parse(value.yValue);
            if (chartModel.maxY > y) {
              maxHeight =
                  maxHeight > chartModel.maxY ? maxHeight : chartModel.maxY;
            } else {
              maxHeight = maxHeight > y ? maxHeight : y;
            }
          }).toList();
        }).toList();
      }
    } else {
      maxHeight = chartModel.maxY;
    }
    setChartData();
    setXPointToBarValueList();
    setYPointToBarValueList();
    if (chartLineArray != null && chartLineArray!.isNotEmpty) {
      setXPointToLineValueList();
      setYPointToLineValueList();
    }
  }

  ///获取横纵坐标
  void setChartData() {
    getAbscissaList();
    getOrdinateList();
  }

  ///获取横坐标内容
  void getAbscissaList() {
    if (maxCross < 2) {
      crossSpacing = xWidth - chartModel.initialPointX;
    } else {
      crossSpacing = (xWidth - chartModel.initialPointX) / (maxCross - 1);
    }
    xList = [];
    for (int i = 0; i < maxCross; i++) {
      double absPoint =
          crossSpacing * i + chartModel.xLeft! + chartModel.initialPointX;
      xList.add(absPoint);
    }
  }

  ///获取纵坐标内容
  void getOrdinateList() {
    double rowSpacing = yHeight / (chartModel.rowCount - 1);
    double ySpac = maxHeight / (chartModel.rowCount - 1);
    yList = [];
    yValue = [];
    for (int i = 0; i < chartModel.rowCount; i++) {
      yList.add(rowSpacing * i + chartModel.yTop! + chartModel.yAxisTop!);
      if (i == 0) {
        int maxYvalue = (maxHeight * 10).ceil();
        String value = (maxYvalue / 10).toString();
        yValue.add(Decimal.parse(value).toString());
      } else {
        double yDouble = ySpac * (chartModel.rowCount - i - 1);
        String value = (yDouble.toStringAsFixed(1)).toString();
        yValue.add(Decimal.parse(value).toString());
      }
    }
  }

  ///获取柱状平均线数组
  void getAvgValuePointList() {
    if (chartModel.avgValues!.isEmpty) {
      for (var i = 0; i < chartBarArray.length; i++) {
        List<ChartBarValue> valueList = chartBarArray[i];
        double sum = valueList.fold(
            0,
            (double preValue, ChartBarValue data) =>
                preValue + double.parse(data.yValue));
        double avgYPoint = sum / valueList.length;
        String value = (avgYPoint.toStringAsFixed(2)).toString();
        chartModel.avgValues!.add(Decimal.parse(value).toString());
        avgYPointList.add(((maxHeight - avgYPoint) / maxHeight) * yHeight +
            chartModel.yTop! +
            chartModel.yAxisTop!);
      }
    } else {
      for (var i = 0; i < chartModel.avgValues!.length; i++) {
        double avgYPoint = double.parse(chartModel.avgValues![i]);
        avgYPointList.add(((maxHeight - avgYPoint) / maxHeight) * yHeight +
            chartModel.yTop! +
            chartModel.yAxisTop!);
      }
    }
  }

  ///给柱状内容数组赋值横坐标值
  void setXPointToBarValueList() {
    xValue = [];
    List<List<ChartBarValue>> barXlist = [];
    for (int i = 0; i < maxCross; i++) {
      List<ChartBarValue> xIndex = [];
      for (int j = 0; j < chartBarArray.length; j++) {
        if (chartBarArray[j].length >= i) {
          ChartBarValue value = chartBarArray[j][i];
          xIndex.add(value);
        }
      }
      barXlist.add(xIndex);
    }
    for (int n = 0; n < barXlist.length; n++) {
      double xPoint = xList[n];
      double sum = barXlist[n].fold(0,
          (double preValue, ChartBarValue data) => preValue + data.barWidth!);
      if (barXlist[n].length > 1) {
        sum = sum + interval! * (barXlist[n].length - 1);
      }
      double leftPoint = xPoint - sum / 2;
      xValue.add(barXlist[n].first.xValue);
      for (int m = 0; m < barXlist[n].length; m++) {
        ChartBarValue item = barXlist[n][m];
        item.xPoint = leftPoint + item.barWidth! / 2;
        leftPoint = leftPoint + item.barWidth! + interval!;
      }
    }
  }

  ///给线内容数组赋值横坐标值
  void setXPointToLineValueList() {
    for (int j = 0; j < chartLineArray!.length; j++) {
      List<ChartLineValue> valueList = chartLineArray![j];
      for (int i = 0; i < valueList.length; i++) {
        ChartLineValue value = valueList[i];
        value.xPoint = xList[i];
      }
    }
  }

  ///给柱状内容数组赋值纵坐标值
  void setYPointToBarValueList() {
    for (int j = 0; j < chartBarArray.length; j++) {
      List<ChartBarValue> valueList = chartBarArray[j];
      for (int i = 0; i < valueList.length; i++) {
        ChartBarValue value = valueList[i];
        double yHvalue = double.parse(value.yValue);
        value.yPoint = ((maxHeight - yHvalue) / maxHeight) * yHeight +
            chartModel.yTop! +
            chartModel.yAxisTop!;
      }
    }
  }

  ///给线内容数组赋值纵坐标值
  void setYPointToLineValueList() {
    for (int j = 0; j < chartLineArray!.length; j++) {
      List<ChartLineValue> valueList = chartLineArray![j];
      for (int i = 0; i < valueList.length; i++) {
        ChartLineValue value = valueList[i];
        double yHvalue = double.parse(value.yValue);
        value.yPoint = ((maxHeight - yHvalue) / maxHeight) * yHeight +
            chartModel.yTop! +
            chartModel.yAxisTop!;
      }
    }
  }
}

class ChartBarValue {
  String xValue;
  String yValue;

  ///文案样式
  TextStyle style;

  ///当点击或者滑动到该区域时是否显示文案，只针对isShowValue=false且isShowClickValue或isShowSlideValue为True才会被使用
  bool isShow;

  ///每段柱状颜色，
  Color? barColor;

  ///柱状宽度，默认16
  double? barWidth;

  ///以下为自动计算，无需传入
  double xPoint = 0;
  double yPoint = 0;

  ChartBarValue(
      {required this.xValue,
      required this.yValue,
      this.barWidth,
      this.style = const TextStyle(fontSize: 12, color: KqThemeColors.text59),
      this.isShow = false,
      this.barColor});
}
